package com.danco.training.zaneuskaya.connection.dao;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public abstract class AbstractDao<T, PK extends Serializable> implements
		GenericDao<T, PK> {

	public abstract T convertResultSet(ResultSet resultSet) throws SQLException;

	public abstract boolean existsInDB(Connection connection, T object)
			throws SQLException;

	public abstract PreparedStatement getUpdateStatement(Connection c, T object)
			throws SQLException;

	public abstract PreparedStatement getInsertStatement(Connection c, T object)
			throws SQLException;

	public abstract PreparedStatement getLastInsertedStatement(Connection c)
			throws SQLException;

	public abstract PreparedStatement readStatement(Connection c, Integer PK)
			throws SQLException;

	public abstract PreparedStatement readAllStatement(Connection c)
			throws SQLException;

	public abstract PreparedStatement getDeleteStatement(Connection c, T object)
			throws SQLException;

	public abstract PreparedStatement getDeleteByIdStatement(Connection c,
			Integer PK) throws SQLException;

	public void create(Connection connection, T object) throws SQLException {

		if (existsInDB(connection, object)) {
			System.out.println("Exists");
		}
		try (PreparedStatement preparedStatement = getInsertStatement(
				connection, object);
				) {
			preparedStatement.executeUpdate();		
		}
	}

	public T read(Connection connection, Integer PK) throws SQLException {

		try (PreparedStatement preparedStatement = readStatement(connection, PK);) {
			T result = null;
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				result = convertResultSet(resultSet);
			}
			return result;
		}
	}

	
	public List<T> readAll(Connection connection) throws SQLException {

		List<T> listT = new ArrayList<T>();
		try (PreparedStatement preparedStatement = readAllStatement(connection);) {
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				T result = convertResultSet(resultSet);
				listT.add(result);
			}
			return listT;
		}
	}

	
	public void update(Connection connection, T object) throws SQLException {

		try (PreparedStatement preparedStatement = getUpdateStatement(
				connection, object);) {
			
				preparedStatement.executeUpdate();
			

		}

	}

	@Override
	public void delete(Connection connection, T object) throws SQLException {

		try (PreparedStatement preparedStatement = getDeleteStatement(
				connection, object);) {
			preparedStatement.executeUpdate();

		}

	}

	public void deleteById(Connection connection, Integer id)
			throws SQLException {
		try (PreparedStatement preparedStatement = getDeleteByIdStatement(
				connection, id);) {
			preparedStatement.executeUpdate();

		}

	}

}
